mod block;
mod consts;
mod heap;
mod page;
mod segment;
mod utils;

pub struct RiAllocator;

use crate::heap::Heap;
use std::alloc::{GlobalAlloc, Layout};
use std::ptr::{null_mut, NonNull};

#[cfg(not(feature = "multi-thread"))]
unsafe impl GlobalAlloc for RiAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        let heap = Heap::single_thread_singleton();
        match heap.alloc(layout) {
            None => null_mut::<u8>(),
            Some(p) => p.cast().as_ptr(),
        }
    }

    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
        let heap = Heap::single_thread_singleton();
        match NonNull::new(ptr) {
            None => return,
            Some(p) => heap.dealloc(p.cast()),
        };
    }
}

#[cfg(feature = "multi-thread")]
unsafe impl GlobalAlloc for RiAllocator {
    unsafe fn alloc(&self, layout: Layout) -> *mut u8 {
        match Heap::thread_local_with(|heap| heap.alloc(layout)) {
            None => null_mut(),
            Some(p) => p.cast().as_ptr(),
        }
    }

    unsafe fn dealloc(&self, ptr: *mut u8, _layout: Layout) {
        match NonNull::new(ptr) {
            None => return,
            Some(p) => Heap::thread_local_with(|heap| heap.dealloc(p.cast())),
        };
    }
}
